import nme.Assets;
import nme.display.Graphics;
import nme.display.DisplayObject;
import nme.display.Sprite;
import nme.display.Bitmap;
import nme.display.BitmapData;

import nme.geom.Rectangle;
import nme.geom.Matrix;
import nme.geom.Point;

import nme.events.Event;
import nme.events.MouseEvent;
import nme.events.KeyboardEvent;
import nme.Lib;

class ModuleEditor extends Sprite implements IGameState
{
	public var _substate:SubState;
	public var _resourceRequest:Int;
	
	private var background:Sprite;
	private var moduleLayer:Sprite;
	private var texture:Bitmap;
	private var moduleMask:Sprite;
	
	public function new ()
	{
		super ();
		_substate = SubState.LOADING_STATE;		
	}
	
	public function getSubstate ():SubState
	{
		return _substate;
	}
	
	public function loading ():Void
	{
	}
	
	public function loadingCompleted ():Bool
	{
		return true;
	}
	
	public function init ():Void
	{
		_substate = SubState.LOOP_STATE;
		
		Lib.current.stage.addEventListener (KeyboardEvent.KEY_DOWN, onkeyboard);
		addEventListener (MouseEvent.MOUSE_MOVE , onMouseMove);
		
		background = new GridTransparent (nme.Lib.current.stage.stageWidth, nme.Lib.current.stage.stageHeight);
		addChild (background);
		
		// moduleMask = new Sprite ();
		// addChild (moduleMask);
		
		var xml:Xml = Xml.parse(Assets.getText ("assets/cricket.xml")).firstElement ();
		var sprite:SpriteData = SpriteData.create (xml);
		var ms:Iterator<ModuleData> = sprite._modules.iterator ();
		
		addChild (texture = new Bitmap (sprite._src));		
		
		addChild (moduleLayer = new Sprite ());
		moduleLayer.addEventListener (MouseEvent.CLICK, onMouseClick);
		moduleLayer.addEventListener (MouseEvent.MOUSE_DOWN, onMouseDown);
		moduleLayer.addEventListener (MouseEvent.MOUSE_UP, onMouseUp);
		moduleLayer.addEventListener (MouseEvent.MOUSE_WHEEL , onMouseWheel);
		
		for (md in ms)
		{
			var module:ModuleSelection = new ModuleSelection (md.bound.x, md.bound.y, md.bound.width, md.bound.height);
			moduleLayer.addChild (module);
			module.alpha = 0.25;
			module.enable = false;
		}
	}

	private var isChange:Bool = true;
	public function loop ():Void
	{
		if (isChange)
		{
			isChange = false;
		}
	}
	
	public function destroy ():Void
	{
	}
	
	private function onkeyboard (e:KeyboardEvent):Void
	{
		trace ("onkeyboard: " + e.keyCode);
		if (topModule != null)
		{
			switch (e.keyCode)
			{
				case 37: topModule.translate (-1, 0);
				case 38: topModule.translate (0, -1);
				case 39: topModule.translate (1, 0);
				case 40: topModule.translate (0, 1);
				case 46: //delete
					selectChild.remove (topModule);
					moduleLayer.removeChild (topModule);
					topModule = null;
			}
		}
		else
		{
			switch (e.keyCode)
			{
				case 45: //add
					var module:ModuleSelection = new ModuleSelection (100, 100, 100, 100);
					moduleLayer.addChild (module);
					module.alpha = 0.25;
					module.enable = false;
					selectChild = [module];
					setSelectChild (module);
			}
		}
	}
	
	private var topModule:ModuleSelection;
	private var topGroup:Array<ModuleSelection>;
	private var selectChild:Array<ModuleSelection>;	
	private function onMouseClick (e:MouseEvent):Void
	{
		trace ("onMouseClick");
		if (isDrag)
		{
			isDrag = false;
			trace ("isDrag = true");
			return;
		}
		trace ("get list");
		var temp:Array<DisplayObject> = moduleLayer.getObjectsUnderPoint (new Point (e.stageX, e.stageY));
		selectChild = new Array <ModuleSelection> ();
		
		while (temp.length > 0)
			if (Std.is (temp[0] , ModuleSelection))
				selectChild.push (cast (temp.shift(), ModuleSelection));
		
		setSelectChild (selectChild[0]);
	}
	
	private var isDrag:Bool;
	private function onMouseDown (e:MouseEvent):Void
	{
	}
	
	private function onMouseUp (e:MouseEvent):Void
	{
	}
	
	private function onMouseMove (e:MouseEvent):Void
	{
		if (e.buttonDown) isDrag = true;
	}
	
	private function onMouseWheel (e:MouseEvent):Void
	{
		if (selectChild == null) return;
		
		var child:ModuleSelection;
		if (e.delta > 0)
		{
			child = selectChild.shift ();
			selectChild.push (child);
		}
		else
		{
			child = selectChild.pop ();
			selectChild.unshift (child);
		}
		
		setSelectChild (child);
	}
	
	private function setSelectChild (child:ModuleSelection):Void
	{
		if (topModule == child) return;
			
		if (topModule != null)
		{
			topModule.alpha = 0.25;
			topModule.enable = false;
			moduleLayer.swapChildren (topModule, child);
		}

		moduleLayer.setChildIndex (child, moduleLayer.numChildren - 1);
		topModule = child;
		topModule.alpha = 1;
		topModule.enable = true;
	}
}